#pragma once
#include <unistd.h>
#include <cstdio>
#include <csignal>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "log.hpp"
#include "err.hpp"

void Daemon(){
    
    //1、忽略异常信号
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

    //2、让自己不要成为组长
    //进程组的组长不能setsid
    //父进程默认是组长，创建子进程，子进程不是组长，让子进程成为守护进程
    if(fork()>0){
        exit(0);
    }

    //3、新建会话，自己成为会话的话首进程
    pid_t ret = setsid();
    if((int)ret == -1){
        logMessage(FATAL, "daemon error, %d:%s", errno, strerror(errno));
        exit(DAEMON_ERR);
    }

    // //4、改变守护进程的工作路径（可选）
    // chdir("/");

    //5、处理fd=0/1/2的问题
    // close(0);
    // close(1);
    // close(2);
    //以读写的方式打开/dev/null垃圾桶文件
    int fd = open("/dev/null", O_RDWR);
    if(fd < 0){
        logMessage(FATAL, "open error, %d:%s", errno, strerror(errno));
        exit(OPEN_ERR);
    }

    //将0/1/2重定向到null垃圾桶
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);

    close(fd);
}